﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;
using Mutzl.Samples.VideoApp.Controls;
using Windows.Data.Html;
using Windows.Web.Syndication;
using System.Linq;

namespace Mutzl.Samples.VideoApp.RssContent.Model
{
    public class Video : ObservableObject, IResizable
    {
        private string _id;
        public string Id
        {
            get { return _id; }
            set
            {
                if (_id == value) return;
                _id = value;
                RaisePropertyChanged(() => Id);
            }
        }

        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                if (_title == value) return;
                _title = value;
                RaisePropertyChanged(() => Title);
            }
        }

        private string _description;
        public string Description
        {
            get { return _description; }
            set
            {
                if (_description == value) return;
                _description = value;
                RaisePropertyChanged(() => Description);
            }
        }

        private string _thumbNailPath;
        public string ThumbNailPath
        {
            get { return _thumbNailPath; }
            set
            {
                if (_thumbNailPath == value) return;
                _thumbNailPath = value;
                RaisePropertyChanged(() => ThumbNailPath);
            }
        }

        private string _posterPath;
        public string PosterPath
        {
            get { return _posterPath; }
            set
            {
                if (_posterPath == value) return;
                _posterPath = value;
                RaisePropertyChanged(() => PosterPath);
            }
        }

        private string _videoPath;
        public string VideoPath
        {
            get { return _videoPath; }
            set
            {
                if (_videoPath == value) return;
                _videoPath = value;
                RaisePropertyChanged(() => VideoPath);
            }
        }

        private string _smoothVideoPath;
        public string SmoothVideoPath
        {
            get { return _smoothVideoPath; }
            set
            {
                if (_smoothVideoPath == value) return;
                _smoothVideoPath = value;
                RaisePropertyChanged(() => SmoothVideoPath);
            }
        }
        
        private Uri _link;
        public Uri Link
        {
            get { return _link; }
            set
            {
                if (_link == value) return;
                _link = value;
                RaisePropertyChanged(() => Link);
            }
        }

        private TimeSpan _duration;
        public TimeSpan Duration
        {
            get { return _duration; }
            set
            {
                if (_duration == value) return;
                _duration = value;
                RaisePropertyChanged(() => Duration);
            }
        }

        private string _author;
        public string Author
        {
            get { return _author; }
            set
            {
                if (_author == value) return;
                _author = value;
                RaisePropertyChanged(() => Author);
            }
        }

        private DateTime _date;
        public DateTime Date
        {
            get { return _date; }
            set
            {
                if (_date == value) return;
                _date = value;
                RaisePropertyChanged(() => Date);
            }
        }

        private List<string> _categories;
        public List<string> Categories
        {
            get { return _categories; }
            set
            {
                if (_categories == value) return;
                _categories = value;
                RaisePropertyChanged(() => Categories);
            }
        }

        //Todo: B01. weitere Properties je nach Bedarf hinzufügen (Speaker, Author, Date, ...)

        //Implementierung von IResizable
        //Width und Height für die variable GridView in der Hauptansicht
        public int Width { get; set; }
        public int Height { get; set; }

        public async static Task<IEnumerable<Video>> GetVideos(string rssUri)
        {
            return await GetVideos(new Uri(rssUri, UriKind.Absolute));
        }

        public async static Task<IEnumerable<Video>> GetVideos(Uri rssUri)
        {
            try
            {
                var client = new SyndicationClient();

                SyndicationFeed feed = await client.RetrieveFeedAsync(rssUri);


                var videos = new List<Video>();

                foreach (var item in feed.Items)
                {

                    // Todo: B03. Hier gegebenenfalls Parsing des RSS anpassen.
                    // Beispiel für diesen RSS-Feed: 
                    // D:\Users\Thomas\Documents\Visual Studio 2012\Projects\Microsoft\VideoAppFramework\VideoAppFramework\Player_B_RssContent\Model\Rss.xml

                    var mediaContentGroup = item.ElementExtensions.SingleOrDefault(e => e.NodeName == "group")
                        .ElementExtensions.OrderByDescending(e => long.Parse(e.AttributeExtensions.SingleOrDefault(a => a.Name == "fileSize").Value));
                    var mp4Node = mediaContentGroup
                        .FirstOrDefault(e => e.AttributeExtensions.SingleOrDefault(a => a.Name == "type").Value == "video/mp4");
                    var smoothVideoNode = mediaContentGroup
                        .FirstOrDefault(e => e.AttributeExtensions.SingleOrDefault(a => a.Name == "url").Value.EndsWith("manifest"));

                    var video = new Video();

                    // Objectinitializer wäre natürlich hübscher, Zuweisung zu Properties ist aber leichter zu debuggen.     

                    video.Id = item.Id;
                    video.Title = item.Title.Text;
                    video.Description = HtmlUtilities.ConvertToText(item.Summary.Text);
                    video.Duration = TimeSpan.FromSeconds(int.Parse(item.ElementExtensions.SingleOrDefault(e => e.NodeName == "duration").NodeValue));
                    video.Link = item.Links.FirstOrDefault().Uri;
                    video.Date = item.PublishedDate.DateTime;
                    video.Author = string.Join(",", item.Authors.Select(a => a.NodeValue).ToList());
                    video.Categories = item.Categories.Select(c => c.Term).ToList();
                    video.ThumbNailPath = item.ElementExtensions.SingleOrDefault(e => e.NodeName == "thumbnail"
                        && e.AttributeExtensions.SingleOrDefault(a => a.Name == "width").Value == "220").AttributeExtensions.SingleOrDefault(a => a.Name == "url").Value;
                    video.PosterPath = item.ElementExtensions.SingleOrDefault(e => e.NodeName == "thumbnail"
                        && e.AttributeExtensions.SingleOrDefault(a => a.Name == "width").Value == "512").AttributeExtensions.SingleOrDefault(a => a.Name == "url").Value;
                    video.VideoPath = mp4Node != null
                        ? mp4Node.AttributeExtensions.SingleOrDefault(a => a.Name == "url").Value
                        : null;
                    video.SmoothVideoPath = smoothVideoNode != null
                        ? smoothVideoNode.AttributeExtensions.SingleOrDefault(a => a.Name == "url").Value
                        : null;

                    videos.Add(video);
                }

                return videos;
            }
            catch
            {
                return null;
            }
        }



        // wird im Design-Modus geladen, damit Layout in Blend und Visual Studio sichtbar ist.
        public static Video CreateDesignVideo()
        {
            return new Video
            {
                Id = Guid.NewGuid().ToString(),
                Title = "Ping 158: Ballmer talks the future, Microsofties hit High School, Stocking the Windows Store, Microsoft Gives",
                Description = HtmlUtilities.ConvertToText(@"I think we finally perfected the virtual Paul experience! Check us out this week and let us know what you think! Here&#39;s the rundown: Microsofties going back to High School&amp;nbsp; [07:42] Ballmer talks about the future [03:08] Stocking the Windows Store with quality apps [16:14] Microsoft gives..a LOT&amp;nbsp; [21:44]"),
                Duration = TimeSpan.FromSeconds(1530),
                Link = new Uri("http://channel9.msdn.com/Shows/PingShow/Ping-158-Ballmer-talks-the-future-Microsofties-hit-High-School-Stocking-the-Windows-Store-Microsoft-"),
                Date = DateTime.Parse("Wed, 17 Oct 2012 05:43:39 GMT"),
                Author = "Laura Foy",
                Categories = new List<string>
                                 {
                                        "Ballmer",
                                        "Education",
                                        "Microsoft",
                                        "Apps",
                                        "Windows Store App"
                                    },
                ThumbNailPath = "http://media.ch9.ms/ch9/81e3/dc03e0fe-266a-45ab-8272-3e89fefb81e3/Ping158_220.jpg",
                PosterPath = "http://media.ch9.ms/ch9/81e3/dc03e0fe-266a-45ab-8272-3e89fefb81e3/Ping158_512.jpg",
                VideoPath = "http://media.ch9.ms/ch9/81e3/dc03e0fe-266a-45ab-8272-3e89fefb81e3/Ping158_high.mp4",
            };
        }


    }
}
